package SinglyLinkedList;

import java.util.function.Consumer;

// 链表整体
public class SinglyLinkedList {
  private Node head; // 头指针

  // 节点类
  private static class Node {
    int value;
    Node next;

    public Node(int value, Node next) {
      this.value = value;
      this.next = next;
    }
  }

  // 头插法
  public void addFirst(int value) {
    // 链表为空的情况
    if (head == null) {
      Node node = new Node(value, null);
      head = node;
    } else {
      // 链表非空的情况
      Node node = new Node(value, head); // 指向head指向的地址
      head = node;
    }
  }
  // 等价于
  // public void addFirst(int value) {
  //   head = new Node(value, head);
  // }

  // 尾插法
  public void addLast(int value) {
    Node last = findLast();
    if (last == null) {
      addFirst(value);
      return;
    }
    last.next = new Node(value, null);
  }

  // 删除第一个节点
  public void removeFirst() {
    if (head == null) {
      throw new IllegalArgumentException(String.format("index [%d] 不合法%n", 0));
    }
    head = head.next;
  }

  // 按索引删除
  public void remove(int index) {
    if (index == 0) {
      removeFirst();
      return;
    }
    Node pervious = findNode(index - 1);
    if (pervious == null) {
      return;
    }
    Node removeNode = pervious.next;
    if (removeNode == null) {
      return;
    }
    pervious.next = removeNode.next;
  }

  // 找数组最后一个节点
  public Node findLast() {
    if (head == null) {
      return null;
    }
    Node p = head;
    while (p.next != null) {
      p = p.next;
    }
    return p;
  }

  // 遍历
  public void loop1() {
    Node p = head;
    while (p != null) {
      System.out.println(p.value + " " + p.next);
      p = p.next;
    }
  }

  public void loop2(Consumer<Integer> consumer) {
    for (Node p = head; p != null; p = p.next) {
      consumer.accept(p.value);
    }
  }

  // 遍历链表输出索引值
  public int forIndex() {
    int i = 0;
    for (Node p = head; p != null; p = p.next, i++) {
      System.out.println(p.value + "index: " + i);
    }
    return i;
  }

  // 通过索引找节点
  private Node findNode(int index) {
    Node p = head;
    int i = 0;
    while (p != null) {
      if (i == index) {
        return p;
      }
      p = p.next;
      i++;
    }
    return null;
  }

  // 返回对应索引的value
  public int getValue(int index) {
    Node node = findNode(index);
    if (node == null) { // 异常处理
      throw new IllegalArgumentException(String.format("index [%d] 不合法%n", index));
    }
    return node.value;
  }

  public void insert(int index, int value) {
    if (index == 0) {
      addFirst(value);
      return;
    }
    Node pervious = findNode(index - 1);
    if (pervious == null) { // 异常处理
      throw new IllegalArgumentException(String.format("index [%d] 不合法%n", index));
    }
    pervious.next = new Node(value, pervious.next);
  }
}
